<!DOCTYPE html>





<html class="theme-next gemini use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="generator" content="Hexo 3.9.0">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=7.3.0">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=7.3.0">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=7.3.0">
  <link rel="mask-icon" href="/images/logo.svg?v=7.3.0" color="#222">
  <meta name="google-site-verification" content="uSLhm-2JUAoM7eOTok7L19IyTJqp7dgwYpDu8dthN5Y" />

<link rel="stylesheet" href="/css/main.css?v=7.3.0">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css?v=4.7.0">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/theme-next/theme-next-needmoreshare2@1/needsharebutton.min.css">
  <link rel="stylesheet" href="/lib/pace/pace-theme-center-atom.min.css?v=1.0.2">
  <script src="/lib/pace/pace.min.js?v=1.0.2"></script>


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '7.3.0',
    exturl: false,
    sidebar: {"position":"left","display":"post","offset":12,"onmobile":true},
    back2top: {"enable":true,"sidebar":true,"scrollpercent":true},
    save_scroll: false,
    copycode: {"enable":true,"show_result":true,"style":"mac"},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: '',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    translation: {
      copy_button: '复制',
      copy_success: '复制成功',
      copy_failure: '复制失败'
    }
  };
</script>

  <meta name="description" content="程序起源 - 第二章前言上一章我们讲述了程序语言发展的基本框架, 有了自定义函数, 代码块, 作用域, 变量类型, 分隔符等概念, 而且涉及到了一点点操作系统的知识. 这一章我们尝试着继续根据程序语言发展的时间线来描述语言发展的历程.">
<meta name="keywords" content="编程,程序起源">
<meta property="og:type" content="article">
<meta property="og:title" content="程序起源 - 第二章">
<meta property="og:url" content="https://www.wootec.top/2019/12/10/Chapter-2/index.html">
<meta property="og:site_name" content="Reverier 个人博客">
<meta property="og:description" content="程序起源 - 第二章前言上一章我们讲述了程序语言发展的基本框架, 有了自定义函数, 代码块, 作用域, 变量类型, 分隔符等概念, 而且涉及到了一点点操作系统的知识. 这一章我们尝试着继续根据程序语言发展的时间线来描述语言发展的历程.">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2019-12-15T15:28:01.112Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="程序起源 - 第二章">
<meta name="twitter:description" content="程序起源 - 第二章前言上一章我们讲述了程序语言发展的基本框架, 有了自定义函数, 代码块, 作用域, 变量类型, 分隔符等概念, 而且涉及到了一点点操作系统的知识. 这一章我们尝试着继续根据程序语言发展的时间线来描述语言发展的历程.">
  <link rel="alternate" href="/atom.xml" title="Reverier 个人博客" type="application/atom+xml">
  <link rel="canonical" href="https://www.wootec.top/2019/12/10/Chapter-2/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: false,
    isPost: true,
    isPage: false,
    isArchive: false
  };
</script>

  <title>程序起源 - 第二章 | Reverier 个人博客</title>
  








  <noscript>
  <style>
  .use-motion .motion-element,
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-title { opacity: initial; }

  .use-motion .logo,
  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  <div class="container sidebar-position-left">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta">

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Reverier 个人博客</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">Hope, Marvel, Youth.</p>
      
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
      
      
      
        
        <li class="menu-item menu-item-home">
      
    
      
    

    <a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i> <br>首页</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-about">
      
    
      
    

    <a href="/about/" rel="section"><i class="menu-item-icon fa fa-fw fa-user"></i> <br>关于</a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-tags">
      
    
      
    

    <a href="/tags/" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i> <br>标签<span class="badge">15</span></a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-categories">
      
    
      
    

    <a href="/categories/" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i> <br>分类<span class="badge">11</span></a>

  </li>
      
      
      
        
        <li class="menu-item menu-item-archives">
      
    
      
    

    <a href="/archives/" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i> <br>归档<span class="badge">16</span></a>

  </li>
  </ul>

</nav>
</div>
    </header>

    

  <a href="https://github.com/Reverier-Xu" class="github-corner" title="My tour on GitHub" aria-label="My tour on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
            

          <div id="content" class="content page-post-detail">
            

  <div id="posts" class="posts-expand">
    

  <article class="post" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://www.wootec.top/2019/12/10/Chapter-2/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Reverier Xu">
      <meta itemprop="description" content="Hope, Marvel, Youth.">
      <meta itemprop="image" content="/images/Reverier.png">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Reverier 个人博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">程序起源 - 第二章

          
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              
                
              

              <time title="创建时间：2019-12-10 23:17:00" itemprop="dateCreated datePublished" datetime="2019-12-10T23:17:00+08:00">2019-12-10</time>
            </span>
          
            

            
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2019-12-15 23:28:01" itemprop="dateModified" datetime="2019-12-15T23:28:01+08:00">2019-12-15</time>
              </span>
            
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/程序起源/" itemprop="url" rel="index"><span itemprop="name">程序起源</span></a></span>

                
                
              
            </span>
          

          
            <span class="post-meta-item" title="阅读次数">
              <span class="post-meta-item-icon">
                <i class="fa fa-eye"></i>
              </span>
              <span class="post-meta-item-text">阅读次数：</span>
              <span class="busuanzi-value" id="busuanzi_value_page_pv"></span>
            </span>
          

                    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="程序起源-第二章"><a href="#程序起源-第二章" class="headerlink" title="程序起源 - 第二章"></a>程序起源 - 第二章</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>上一章我们讲述了程序语言发展的基本框架, 有了自定义函数, 代码块, 作用域, 变量类型, 分隔符等概念, 而且涉及到了一点点操作系统的知识. 这一章我们尝试着继续根据程序语言发展的时间线来描述语言发展的历程.</p>
<a id="more"></a>

<h2 id="编译器"><a href="#编译器" class="headerlink" title="编译器"></a>编译器</h2><p>随着计算器的不断改良, 越来越多的人开始使用这样一种可以进行数学运算的语言. 但是呢, 由于新的标准与规定, 计算器程序为了支持这些新的标准也变得越来越庞大. 随着计算机的大量普及, 互联网的发展却并没有那么迅速. 在每一台计算机上都安装一个这样的计算器逐渐变得有些不太可能. 为了解决这个麻烦, 人们开始了另一些大胆的想法.</p>
<p>所有的程序都是在机器指令和基于机器指令翻译的汇编语言的基础上编写出来的, 那我们可不可以设计一种新的程序, 直接把这种数学语言翻译成机器代码执行呢? 这样就可以脱离计算器而将编写好的程序在任何计算机上执行.</p>
<p>开发者们突然想到, 如果这样说, 那么这门数学语言就正式转变成了一门编程语言了! 这个任务开始热火朝天的进行起来, 最终开发者们编写了另一个程序, 他可以把这种语言进行语义分析, 然后经过一系列过程把它转化成一个可以直接在计算机上运行的程序. 为了区别之前的计算器程序, 开发者们把之前计算器那种一边输入一边执行或者一边读取一边执行的程序叫做<strong>解释器</strong>, 把这种可以把代码变成程序的叫做<strong>编译器</strong>.</p>
<h2 id="设计输入输出时的麻烦"><a href="#设计输入输出时的麻烦" class="headerlink" title="设计输入输出时的麻烦"></a>设计输入输出时的麻烦</h2><p>在开发编译器的过程中遇到了一些问题, 比如说, 还延续之前解释器那样, 每计算一次就打印一次结果嘛..? 这样搞感觉程序的实用性很低, 一个稍微复杂点的过程就会输出一大堆莫名其妙的东西. 这样搞感觉有点智障. 开发者们想着, 能不能按照函数的方式, 组织一个专门用来打印信息的函数出来, 只有编写者调用这个函数的时候才输出特定的信息呢? 这个函数很快就设计好了, 使用的是汇编语言 + 数学语言定义的方式, 混杂着实现了出来. 但是怎么调用这个函数呢? 开发者为这个函数写了一个声明, 取<code>print format</code>的意思, 把这个函数命名为<code>printf</code>, 但是怎么样才能设计出来一个使用方便的输出函数而又不失输出时格式的灵活性呢? 或者说, 如果我想打印一句话, 应该怎么告诉这个函数呢? 开发者由抽象到具体, 发现原有的设计体系并不足够支撑起这么一个任务, 于是开发者们只好继续增加这个语言的复杂度, 设计一些新的东西同时尽量保持语言的统一性, 不参杂进去太多的元素.</p>
<p>最终经过一大堆设计和实现, 开发者们实现了这个函数, 它的函数原型是这个样子:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">printf</span> <span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *__format, ...)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">register</span> <span class="keyword">int</span> __retval;</span><br><span class="line">    __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );</span><br><span class="line">    __retval = __mingw_vprintf( __format, __local_argv );</span><br><span class="line">    __builtin_va_end( __local_argv );</span><br><span class="line">    <span class="keyword">return</span> __retval;</span><br><span class="line">    <span class="comment">/* 在VSCode里面, 你可以通过在你编写的代码里使用printf, 然后右键点击printf, 选择查看定义,</span></span><br><span class="line"><span class="comment">    就可以看见这个定义. VSCode提供了定义查询的功能, 不仅适用于库函数的查询, 如果你自己写</span></span><br><span class="line"><span class="comment">    了很长的代码, 里面有若干个自定义函数, 在你使用的时候不想把代码翻到开头看函数定义再</span></span><br><span class="line"><span class="comment">    翻回来继续写代码, 就可以先写出这个函数的名字, 然后右键, 查看定义, 就可以在不翻来翻去的</span></span><br><span class="line"><span class="comment">    情况下快速查看这个函数的定义.*/</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个函数的定义是不是看起来很奇怪? 他里面写了一大堆乱七八糟的东西. 那些都属于函数, 开发者们为了使程序易于阅读和重用, 编写了许多可以相互使用的函数, <code>printf</code>实际上是一系列函数的包装, 这一系列的函数会处理整个像屏幕上打印特定格式的特定字符的复杂过程.</p>
<p>我们不用去理解<code>printf</code>里面那些长得和乱码并没有什么去别的东西, 我们只需要看见第一行的声明就可以了.</p>
<p><code>int printf(const char * __format, ...)</code></p>
<p>就是这一行. 为了弄明白这个输入输出函数是什么鬼, 我们还需要知道, 开发者们又在这门数学语言里面加入了什么骚操作.</p>
<h2 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h2><p>开发者们为了能一次性的输出大量数据, 同时为了解决人们对于大量同类数据计算的需求, 比如一年的每个月都有多少天这种问题, 设计了一个叫做数组的概念. 所谓数组, 就是一堆同类型的变量组成的一个集合. 我们可以通过像声明变量那样简单而快速的声明一个数组进行使用.</p>
<p>声明一个数组, 我们只需要:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;变量类型&gt; &lt;变量名称&gt;[&lt;数组里面同类变量的个数&gt;]; <span class="comment">// 人们通常把同类变量的个数叫做数组大小.</span></span><br><span class="line"><span class="keyword">int</span> x[<span class="number">10</span>]; <span class="comment">// x是一个包含10个整数类型元素的数组</span></span><br><span class="line"><span class="comment">// 其他的类型都可以这么做</span></span><br></pre></td></tr></table></figure>

<p>使用起来也挺简单的. 最开始, 开发者们希望按照数学上的习惯, 如果用户编写<code>x[7]</code>, 就代表x里面的第7个元素. 但是在开发者们在编译器里面实现这个功能的时候, 发现事情并不像想象中的那么简单. 比如说产生了以下几个问题:</p>
<blockquote>
<p>1, 如果x[10]是一个有十个元素的数组, 那么只写x, 这个x是代表什么呢?<br>2, 我们根据用户的输入, 在内存里创造了一连串同样的变量, 应该怎么快速有效的读取到用户指定的那个变量呢? 难道按照顺序, 如果用户编写<code>x[100]</code>, 就顺着第一个元素找99次找到第100个变量吗? 那如果我声明了一个大小为一亿的数组呢? 按照遍历的方式运算时间会很令人感动的.</p>
</blockquote>
<p>还有一些问题这里不再列举. 为了结局这个新的问题, 开发者们又设计了一个新东西.</p>
<h2 id="指针"><a href="#指针" class="headerlink" title="指针"></a>指针</h2><p>开发者们想到, 变量是存储在内存之中的, 而内存的每个固定大小的空间都像住户一样被分配了门牌号. 开发者将内存里这个门牌号定义为<code>unsigned int</code>类型 (因为没有变量会住在负内存里), 然后数组就有了一种新的解决方案.</p>
<p>当用户输入<code>int x[100]</code>来定义一个数组的时候, 首先在内存里开辟出来一块连在一起的内存, 大小是100个整数变量的大小. 然后另外声明一个<code>unsigned int</code>类型的变量, 里面存储这块大内存里第一个变量的内存地址. 这样, 当用户使用<code>x[75]</code>的时候, 编译器就可以先计算75个int类型变量的大小, 然后计算x中储存的第一个元素的内存地址和75个变量大小的和, 得到了一个新的地址, 这个新的地址就是第75个元素所在的地址, 直接从内存里取出这个变量就可以了.</p>
<p>经过这样的设计, 数组终于被实现了出来. 人们重新设计了乘号, 也就是<code>&#39;*&#39;</code>, 如果<code>x</code>代表内存地址, 那么<code>*x</code>就代表从这个内存地址上的变量. 同样的, 人们也设计了<code>&#39;&amp;&#39;</code>号, 如果<code>x</code>是一个变量, 那么<code>&amp;x</code>就代表<code>x</code>所在的内存地址. 开发者们把这个存储内存地址的变量形象的称为指针. 指针顾名思义, 就是指向某个特定类型的变量的内存地址的变量, 这句话有点长, 小理解一下问题不大. 关于指针的关系我们可以这么理解:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">pig LYQ; <span class="comment">// 在内存中声明了一个pig类型的变量LYQ</span></span><br><span class="line">pig *LYQdeHome = &amp;LYQ; <span class="comment">// 先找到LYQ, 然后把他住的地方的地址存在LYQdeHome之中</span></span><br><span class="line">Go(LYQdeHome); <span class="comment">// 去LYQ家, 这一句等同于 go(&amp;LYQ); 这里的go()函数以及上面的pig类型都是假定的.</span></span><br><span class="line">EatWith(LYQ); <span class="comment">// 和LYQ一块儿吃饭, 等同于EatWith(*LYQdeHome);</span></span><br></pre></td></tr></table></figure>

<p>这里有一个小小的趣事, 也就是, 如果按照<code>指针地址 + 偏移地址 = 数组内第N个元素的地址</code>的方式来设计数组, 那么我们可以把<code>x[75]</code>解释成 <code>*(x + 75)</code>. 但是…这么做往往是错的..因为, 如果你想要取出数组里面的第一个元素, 按照这个办法应该是<code>x[1]</code>, 解释成地址也就是<code>*(x + 1)</code>, 但是x储存的就是第一个元素的地址啊, 正确答案应该是<code>*x</code>. 那么写成数组的表示方式, 也就是<code>x[0]</code>. 于是开发者们爆发了一场口头战争, 关于数组编号 (更专业点的叫法叫<strong>数组下标</strong>) 应该从0开始还是从1开始.</p>
<blockquote>
<p>“按照中庸的思想, 如果我们对于一个问题争执不下, 我们可以考虑以折衷的思想来处理这个问题. 对于数组下标应当从0开始还是从1开始, 我给出的折中方案是用0.5作为数组下标的开始, 可是两派人士都不加思考的就否决了, 然后把我打了一顿并赶出了实验室.”<br>——一位参与了编译器开发的程序员, 躺在医院里接受采访时如是说</p>
</blockquote>
<p>最终为了保持指针的有效性, 人们最终决定数组下标应当从0开始, <code>x[75]</code>依旧会被解释成<code>*(x + 75)</code>, 但是它表示的是数组里面第76个元素.</p>
<h2 id="字符串"><a href="#字符串" class="headerlink" title="字符串"></a>字符串</h2><p>在上一章里面, 开发者们设计了一个叫做char的字符类型, 但是全章好像都没有用过, 在数学计算的过程里面好像也用不着这么一个设计. 没错, 这个变量就是专门为了输入输出而设计的. 一个英文句子, 可以看成是一个由一堆字符组成的数组吧? 开发者们找到了计算机协会, 计算机协会的一群大佬思索了很久给出了一张表, 也就是传说中的ASCII, 美国标准信息交换码查询表. 里面给128个字符进行了编号, 从0 - 127. 这些字符里面包括了大小写字母, 数字, 常用标点符号, 以及一些可以控制计算机的字符, 比如用某些字符来表示换行, 另一些字符可以让计算机的蜂鸣器”滴~”的响一声. 有了这张表, 开发者们实现字符就简单了, 只需要往char类型里面存储数字就可以了, 计算过程和处理过程中处理的也都是数字, 只有最终显示的时候, 再对照着ASCII表来查询char变量里面存储的那个数字对应什么字符.</p>
<p>但是, 在代码里面用整数操作字符也太难为人了吧, 难不成每个程序员都要背一遍查询表? 开发者们表示他们已经解决了, 他们在编译器里面内置了一张查询表, 编写者可以在代码里面用单引号括起来一个字符: <code>&#39;x&#39;</code>, 编译器遇到这个x的时候就会自动按照查询表将其翻译成数字.这样一来, 我们就可以按照:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> a = <span class="string">'x'</span>;</span><br><span class="line">a = <span class="string">'y'</span>;</span><br><span class="line"><span class="keyword">int</span> number = a - <span class="string">'a'</span> + <span class="number">1</span>; <span class="comment">// 计算y在字母表里面是第几个字母</span></span><br></pre></td></tr></table></figure>

<p>来对字符进行操作了. 为了表示那些表示不出来的字符, 比如换行符, 开发者表示可以采用转义的方式, 比如用<code>&#39;\n&#39;</code>来表示换行的字符.</p>
<p>于是我们就可以用数组的形式来表示一句话. 但是一个小问题, 我们怎么表示一句话的结尾呢? 鉴于所有的字符都有表示出来的价值, 所以把哪个字符定义成字符串的结尾呢? 开发者们想了想, 不如就把数值0定义成字符串的结尾吧. 在ASCII表里面, 0所对应的字符是一个空字符, 没有任何含义, 用来当作字符串的结尾刚刚好!</p>
<p>于是, 就这么决定了, 每一个字符数组的末尾加上一个<code>&#39;\0&#39;</code>字符, 就可以组成一个合法的字符串. 为了表示的方便, 开发者们规定可以用双引号括起来的一串话来表示字符串. 例如:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"Hello World!"</span></span><br></pre></td></tr></table></figure>

<p>这种表示方法是默认字符串结尾有<code>\0</code>字符的, 不用显式地把它写出来也可以运作.</p>
<p>开发者们还很贴心的重新设计了等于号的作用, 支持把一个字符串通过指针赋值到一个char类型的数组里面. 就像这样:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> x[<span class="number">13</span>];</span><br><span class="line">x = <span class="string">"Hello World"</span>;</span><br></pre></td></tr></table></figure>

<p>这种方便的形式受到了编写者的一致好评. 但是有一点是需要注意的, <code>&quot;Hello World!&quot;</code>里面包括空格和感叹号, 总共有十二个字符, 但是由于<code>&quot;&quot;</code>表示的字符串结尾自带一个<code>&#39;\0&#39;</code>, 所以我们要声明一个拥有13个元素的数组才可以存下这个字符串. 没有<code>\0</code>结尾的字符数组只能被称为是字符数组, 并不能被称之为一个字符串, 输入输出函数碰到字符数组的时候也会寻找<code>&#39;\0&#39;</code>作为字符串的结尾, 一个没有结尾的字符数组并不能被正确的处理, 会出一些问题.</p>
<p>另一个问题, <code>&quot;Hello World!&quot;</code>本身的值是什么呢? 其实, 直接写出来的字符串, 编译器会默认分配一个常量的位置给他们. 意思也就是使用到<code>&quot;Hello World!&quot;</code>的时候, 内存里会多出来一个名字叫aHelloWorld的变量, 他的定义如下:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> * aHelloWorld = &#123;<span class="string">'H'</span>,<span class="string">'e'</span>,<span class="string">'l'</span>,<span class="string">'l'</span>,<span class="string">'o'</span>,<span class="string">' '</span>,<span class="string">'W'</span>,<span class="string">'o'</span>,<span class="string">'r'</span>,<span class="string">'l'</span>,<span class="string">'d'</span>,<span class="string">'!'</span>,<span class="string">'\0'</span>&#125;;</span><br></pre></td></tr></table></figure>

<p>const是另一个关键字, 可以放在任何变量类型前面当修饰, 表示这个变量是个常量, 其值不可被改变.</p>
<p>因此我们使用到<code>&quot;Hello World!&quot;</code>的时候, 实际上我们写的代码是<code>char x[13] = aHelloWorld</code>, 因此不难理解, “Hello World!”这个字符串其实传递的, 也是一个指针, 指向常量aHelloWorld的第一个元素, 也就是字母’H’. 不过由于是在给一个字符数组赋值, 所以等号会用这个指针把aHelloWorld的值扫描一遍, 然后逐个复制给x[].</p>
<h2 id="库和预编译指令"><a href="#库和预编译指令" class="headerlink" title="库和预编译指令"></a>库和预编译指令</h2><p>好了, 经过千辛万苦和一大堆乱七八糟的定义, <code>printf</code>函数终于被定义好了. 但是问题来了, 编写者难不成每一次都要把这个函数的所有定义都复制到自己的代码里面嘛? 那样会严重降低程序的可读性..而且这样搞成本太高了. 开发者们本想把这个函数调用内置到编译器里面, 但是那样内置之后, <code>printf</code>就变成了一个只有声明没有定义的函数了.. 这么破坏规矩可并不是人们想看到的.</p>
<p>于是开发者们想了好久, 最终决定写一种预处理的机制, 用户可以下载开发者们写好的函数库, 里面包含了各种函数的定义, 如果编写者想使用这些函数, 只需要用预处理指令来包含这个库, 编译器在编译之前就会首先把这个库里面相关的函数定义复制到用户所写的代码前面组成一份包含完整定义的新代码文件, 这个时候再进行编译, 就方便的多了.</p>
<p>预处理指令首先设计了两个, 一个是 <code>#include</code>, 另一个是 <code>#define</code>.</p>
<p><code>#include &lt;包含文件&gt;</code>这样编写之后, 编译器就会在系统库目录里面寻找这个文件并把这个文件里面的函数复制到用户的代码里面. 如果写<code>#include &quot;包含文件&quot;</code>, 那么编译器会在用户当前的文件夹里面寻找这个文件. 这样的设计给了用户很大的自由, 让用户也可以编写自己的库.</p>
<p><code>#define sign string</code>指令用来取别名, 我们可以用sign来代替后面的string, 编译器在执行之前就可以扫描一遍代码, 然后把所有出现sign的部分全部都用string来替换. 这个指令其实还有一些很骚气的用法, 比如…</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BEGIN int main() &#123;</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> END &#125;</span></span><br><span class="line"></span><br><span class="line">BEGIN</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Hello World!\n"</span>);</span><br><span class="line">END</span><br></pre></td></tr></table></figure>

<p>这个代码真的可以运行!</p>
<h2 id="输出的实现"><a href="#输出的实现" class="headerlink" title="输出的实现"></a>输出的实现</h2><p>从上面的代码里面我们大概看见了输入输出应该怎么去做. 还记得第二章开头贴出来的那个printf函数的生命吗? 我们重新贴出来看看:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">printf</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> * __format, ...)</span> </span>&#123;balabala...;&#125;</span><br></pre></td></tr></table></figure>

<p>从这个函数的参数列表上面我们就可以发现这个函数应当怎么用.</p>
<p>首先, 我们看见了<code>printf</code>的第一个参数<code>const char * __format</code>, 这是一个名字为<code>__format</code>的参数, 类型是<code>char *</code>, 是个指针. 这告诉我们这个函数会接受一个字符串, 我们只需要把字符串的首位地址传入进去就可以了. 根据之前讲述的, 字符串本质上也是指向真实字符串的一个指针, 所以我们可以很方便的用<code>prinf(&quot;Hello World!&quot;);</code>, 这样就可以在屏幕上打印出来一句<code>Hello World!</code>.</p>
<p>但是我们发现printf的参数并不只是只有一个<code>__format</code>啊? 后面那个省略号是什么? 省略号表示参数的数量是不确定的, 意思也就是printf可以接受若干个变量当参数. 这个是开发者们为了使printf更加灵活而设计的. 我们有时候需要在一个句子里面输出一些变量的值, 在开发者们的设计之下, <code>printf</code>里面用<code>%&lt;字母&gt;</code>的形式来表示占位符, 占位符的数量和类型与printf省略掉的参数列表应当是相匹配的. 占位符的使用建议百度, 此处不再赘述. 这样, 我们就可以通过<code>printf(&quot;The Result is: %d\n&quot;, x);</code>来进行输出了.</p>
<p>我们发现, printf这个函数和其他的函数一样, 是有返回值的 (这一点很重要! 因为几乎所有的C语言教材都不会讲到这个, 但是这个返回值真的存在!). 返回值是输出的字符串的长度. 考虑一句printf的用处:</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">"%d"</span>,<span class="built_in">printf</span>(<span class="string">"%d"</span>,<span class="built_in">printf</span>(<span class="string">"%d"</span>,<span class="number">43</span>)));</span><br></pre></td></tr></table></figure>

<p>你猜猜他会输出什么?</p>
<h1 id="预告"><a href="#预告" class="headerlink" title="预告"></a>预告</h1><p>下期会接着讲述一些库函数, 在紧接着的设计过程中, 数学家们发现了一些新的逻辑结构, 希望开发者们能顶着秃头的压力开发出来……开发出来</p>

      
    </div>

    
    
    
<div>
  
    <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">--本文结束-😁-感谢您的阅读!--</div>
    
</div>

  
</div>
      

      

      
        
      
      

      

      <footer class="post-footer">
        
          
            
          
          <div class="post-tags">
            
              <a href="/tags/编程/" rel="tag"><i class="fa fa-tag"></i> 编程</a>
            
              <a href="/tags/程序起源/" rel="tag"><i class="fa fa-tag"></i> 程序起源</a>
            
          </div>
        

        
  <div class="post-widgets">
    <div class="social-share">
      
      
        <div id="needsharebutton-postbottom">
          <span class="btn">
            <i class="fa fa-share-alt" aria-hidden="true"></i>
          </span>
        </div>
      
    </div>
  
  </div>


        
          <div class="post-nav">
            <div class="post-nav-next post-nav-item">
              
                <a href="/2019/12/03/Chapter-1/" rel="next" title="程序起源 - 第一章">
                  <i class="fa fa-chevron-left"></i> 程序起源 - 第一章
                </a>
              
            </div>

            <span class="post-nav-divider"></span>

            <div class="post-nav-prev post-nav-item">
              
            </div>
          </div>
        
      </footer>
    
  </div>
  
  
  
  </article>
  </div>


          </div>
          
    
    
  <div class="comments" id="comments">
    <div id="lv-container" data-id="city" data-uid="MTAyMC80NjE1MC8yMjY2MQ=="></div>
  </div>
  
  

        </div>
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-overview">

          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image"
      src="/images/Reverier.png"
      alt="Reverier Xu">
  <p class="site-author-name" itemprop="name">Reverier Xu</p>
  <div class="site-description motion-element" itemprop="description">Hope, Marvel, Youth.</div>
</div>
  <nav class="site-state motion-element">
      <div class="site-state-item site-state-posts">
        
          <a href="/archives/">
        
          <span class="site-state-item-count">16</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
    
      
      
      <div class="site-state-item site-state-categories">
        
          
            <a href="/categories/">
          
        
        
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
        <span class="site-state-item-count">11</span>
        <span class="site-state-item-name">分类</span>
        </a>
      </div>
    
      
      
      <div class="site-state-item site-state-tags">
        
          
            <a href="/tags/">
          
        
        
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
          
        
        <span class="site-state-item-count">15</span>
        <span class="site-state-item-name">标签</span>
        </a>
      </div>
    
  </nav>
  <div class="feed-link motion-element">
    <a href="/atom.xml" rel="alternate">
      <i class="fa fa-rss"></i>RSS
    </a>
  </div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="https://github.com/Reverier-Xu" title="GitHub &rarr; https://github.com/Reverier-Xu" rel="noopener" target="_blank">GitHub</a>
      </span>
    
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="https://stackoverflow.com/users/12383772/reverier" title="StackOverflow &rarr; https://stackoverflow.com/users/12383772/reverier" rel="noopener" target="_blank">StackOverflow</a>
      </span>
    
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="mailto:reverier.xu@gmail.com" title="E-Mail &rarr; mailto:reverier.xu@gmail.com" rel="noopener" target="_blank">E-Mail</a>
      </span>
    
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="https://weibo.com/dreamskytech" title="微博 &rarr; https://weibo.com/dreamskytech" rel="noopener" target="_blank">微博</a>
      </span>
    
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="https://www.zhihu.com/people/reverier-78/activities" title="知乎 &rarr; https://www.zhihu.com/people/reverier-78/activities" rel="noopener" target="_blank">知乎</a>
      </span>
    
      <span class="links-of-author-item">
      
      
        
      
      
        <a href="https://user.qzone.qq.com/773389969" title="Qzone &rarr; https://user.qzone.qq.com/773389969" rel="noopener" target="_blank">Qzone</a>
      </span>
    
  </div>
  <div class="cc-license motion-element" itemprop="license">
    
  
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" rel="noopener" target="_blank"><img src="/images/cc-by-nc-sa.svg" alt="Creative Commons"></a>
  </div>


  <div class="links-of-blogroll motion-element links-of-blogroll-block">
    <div class="links-of-blogroll-title">
      <i class="fa  fa-fw fa-link"></i>
      友情链接~
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://www.std-frank.club/" title="https://www.std-frank.club/" rel="noopener" target="_blank">Frank</a>
        </li>
      
        <li class="links-of-blogroll-item">
          <a href="https://eqqie.cn/" title="https://eqqie.cn/" rel="noopener" target="_blank">赤道企鹅</a>
        </li>
      
        <li class="links-of-blogroll-item">
          <a href="https://cor1e.cn/" title="https://cor1e.cn/" rel="noopener" target="_blank">Cor1e</a>
        </li>
      
        <li class="links-of-blogroll-item">
          <a href="https://yunq1ao.com/" title="https://yunq1ao.com/" rel="noopener" target="_blank">yunq1ao</a>
        </li>
      
        <li class="links-of-blogroll-item">
          <a href="https://shal10w.github.io/" title="https://shal10w.github.io/" rel="noopener" target="_blank">shal10w</a>
        </li>
      
        <li class="links-of-blogroll-item">
          <a href="https://blog.csdn.net/arttnba3/" title="https://blog.csdn.net/arttnba3/" rel="noopener" target="_blank">arttnba3</a>
        </li>
      
    </ul>
  </div>


        </div>
      </div>
      <!--noindex-->
        <div class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
            
            
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#程序起源-第二章"><span class="nav-number">1.</span> <span class="nav-text">程序起源 - 第二章</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#前言"><span class="nav-number">1.1.</span> <span class="nav-text">前言</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#编译器"><span class="nav-number">1.2.</span> <span class="nav-text">编译器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#设计输入输出时的麻烦"><span class="nav-number">1.3.</span> <span class="nav-text">设计输入输出时的麻烦</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#数组"><span class="nav-number">1.4.</span> <span class="nav-text">数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#指针"><span class="nav-number">1.5.</span> <span class="nav-text">指针</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#字符串"><span class="nav-number">1.6.</span> <span class="nav-text">字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#库和预编译指令"><span class="nav-number">1.7.</span> <span class="nav-text">库和预编译指令</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#输出的实现"><span class="nav-number">1.8.</span> <span class="nav-text">输出的实现</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#预告"><span class="nav-number">2.</span> <span class="nav-text">预告</span></a></li></ol></div>
            

          </div>
        </div>
      <!--/noindex-->
      
        <div class="back-to-top motion-element">
          <i class="fa fa-arrow-up"></i>
          
            <span id="scrollpercent"><span>0</span>%</span>
          
        </div>
      

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; 2019 – <span itemprop="copyrightYear">2020</span>
  <span class="with-love" id="animate">
    <i class="fa fa-free-code-camp"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Reverier Xu</span>
</div>
<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  

        
<div class="busuanzi-count">
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span class="post-meta-item-icon">
      <i class="fa fa-user"></i>
    </span>
    <span class="site-uv" title="总访客量">
      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
    </span>
  
    <span class="post-meta-divider">|</span>
  
    <span class="post-meta-item-icon">
      <i class="fa fa-eye"></i>
    </span>
    <span class="site-pv" title="总访问量">
      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
    </span>
  
</div>








        
      </div>
    </footer>
      <div class="reading-progress-bar"></div>

    
  
  <div id="needsharebutton-float">
    <span class="btn">
      <i class="fa fa-share-alt" aria-hidden="true"></i>
    </span>
  </div>
<script src="//cdn.jsdelivr.net/gh/theme-next/theme-next-needmoreshare2@1/needsharebutton.min.js"></script>
<script>
    pbOptions = {};
      pbOptions.iconStyle = "default";
    
      pbOptions.boxForm = "horizontal";
    
      pbOptions.position = "bottomCenter";
    
      pbOptions.networks = "Weibo,Wechat,Douban,QQZone,Twitter,Facebook";
    
    new needShareButton('#needsharebutton-postbottom', pbOptions);
    flOptions = {};
      flOptions.iconStyle = "default";
    
      flOptions.boxForm = "horizontal";
    
      flOptions.position = "middleRight";
    
      flOptions.networks = "Weibo,Wechat,Douban,QQZone,Twitter,Facebook";
    
    new needShareButton('#needsharebutton-float', flOptions);
</script>


  </div>

  
    
  
  <script color='0,0,255' opacity='0.5' zIndex='-1' count='99' src="/lib/canvas-nest/canvas-nest.min.js"></script>
  <script src="/lib/jquery/index.js?v=3.4.1"></script>
  <script src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  <script src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

<script src="/js/utils.js?v=7.3.0"></script><script src="/js/motion.js?v=7.3.0"></script>

<script src="/js/schemes/pisces.js?v=7.3.0"></script>



<script src="/js/next-boot.js?v=7.3.0"></script>




  
  <script>
    (function(){
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      bp.src = (curProtocol === 'https') ? 'https://zz.bdstatic.com/linksubmit/push.js' : 'http://push.zhanzhang.baidu.com/push.js';
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
    })();
  </script>




























  

  

  


  
  <script src="/js/scrollspy.js?v=7.3.0"></script><script src="/js/post-details.js?v=7.3.0"></script>


<script>
  window.livereOptions = {
    refer: location.pathname.replace(CONFIG.root, '').replace('index.html', '')
  };
  (function(d, s) {
    var j, e = d.getElementsByTagName(s)[0];
    if (typeof LivereTower === 'function') { return; }
    j = d.createElement(s);
    j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
    j.async = true;
    e.parentNode.insertBefore(j, e);
  })(document, 'script');
</script>

  <link rel="stylesheet" href="/dist/APlayer.min.css">
  <div id="aplayer"></div>
  <script type="text/javascript" src="/dist/APlayer.min.js"></script>
  <script type="text/javascript" src="/dist/music.js"></script>
</body>
</html>
<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/src/clicklove.js"></script>
